import 'dart:convert';
import 'dart:io';

import 'package:dio/dio.dart';

import 'interceptors/CommonHeaderInterceptor.dart';
import 'interceptors/DioLogInterceptor.dart';

const String HOST = "https://1x.com/";
const int CONNECT_TIMEOUT = 10000;
// const int RECEIVE_TIMEOUT = 10*1000;//
const int RECEIVE_TIMEOUT = 0; // 由于下载文件时候一直出现 DioErrorType.RECEIVE_TIMEOUT 改成0
// "Content-Type": "application/x-www-form-urlencoded"
// final String CONTENT_TYPE = ContentType.html.toString();
final String CONTENT_TYPE = "application/x-www-form-urlencoded";

class HttpUtil {
  factory HttpUtil() => _httpInstance();
  static HttpUtil _instance;
  Dio _dio;
  BaseOptions orgOption;

  static HttpUtil _httpInstance() {
    if (_instance == null) {
      _instance = HttpUtil._init();
    }
    return _instance;
  }

  HttpUtil._init() {
    orgOption = BaseOptions(
        contentType: CONTENT_TYPE,
        connectTimeout: CONNECT_TIMEOUT,
        receiveTimeout: RECEIVE_TIMEOUT,
        baseUrl: HOST);
    _dio = new Dio(orgOption);
    _dio.interceptors.add(CommonHeaderInterceptor());
    _dio.interceptors.add(DioLogInterceptor());
  }

  //拦截器添加
  addInterceptor(Interceptor interceptor) {
    if (null != _dio) {
      _dio.interceptors.add(interceptor);
    }
  }

  addInterceptors(List<Interceptor> interceptorList) {
    if (null != _dio) {
      _dio.interceptors.addAll(interceptorList);
    }
  }

  void post(String url,
      {Map<String, dynamic> data, Function success, Function error}) async {
    // 发送post请求
    _sendRequest(url, 'post', success, data: data, error: error);
  }

  void get(String url,
      {Map<String, dynamic> data, Function success, Function error}) async {
    // 数据拼接
    if (data != null && data.isNotEmpty) {
      StringBuffer options = new StringBuffer('?');
      data.forEach((key, value) {
        options.write('${key}=${value}&');
      });
      String optionsStr = options.toString();
      optionsStr = optionsStr.substring(0, optionsStr.length - 1);
      url += optionsStr;
    }
    // 发送get请求
    await _sendRequest(url, 'get', success, error: error);
  }

  // 请求处理
  Future _sendRequest(String url, String method, Function success,
      {Map<String, dynamic> data, Function error}) async {
    int _code;
    String _msg;
    var _backData;
    try {
      Map<String, dynamic> dataMap = data == null ? new Map() : data;

      Response response;

      if (method == 'get') {
        response = await _dio.get(url);
      } else {
        response = await _dio.post(url, data: dataMap);
      }

      if (response.statusCode != 200) {
        _msg = '网络请求错误,状态码:' + response.statusCode.toString();
        _handError(error, _msg);
        return;
      }

      // 返回结果处理
      Map<String, dynamic> resCallbackMap = response.data;
//
//      _code = resCallbackMap['code'];
//      _msg = resCallbackMap['msg'];
//       Map<String, dynamic> header = resCallbackMap['header'];
      int _code = resCallbackMap['code'];
      if (_code != 1) {
        _msg = '' + resCallbackMap['msg'];
        _handError(error, _msg);
        return;
      }

      _backData = resCallbackMap['data'];

//      "payload": "",
//    "header": {
//    "msg": "Success",
//    "code": 200
//    }

      if (success != null) {
//        if (_code == 0) {
        success(_backData);
//        } else {
//          String errorMsg = _code.toString() + ':' + _msg;
//          _handError(error, errorMsg);
//        }
      }
    } catch (exception) {
//      {"payload":"","header":{"msg":"登录失败，密码错误！","code":400}}

      String msg = '数据请求错误：' + exception.toString();
      if (exception is DioError) {
        DioError exception2 = exception;
        if (exception2.response != null) {
          Map<String, dynamic> data = exception2.response.data;
          if (data != null && data["header"] != null) {
            msg = data["header"]["msg"];
          }
        }
      }

      _handError(error, msg);
    }
  }

  /*

  * 下载文件*/
//urlPath 下載路徑
  //savePath 保持路徑
  downloadFile(urlPath, savePath,
      {Function downloadComplete,
      Function downloadProgress,
      Function error}) async {
    try {
      Response response = await _dio.download(urlPath, savePath,
          onReceiveProgress: (int count, int total) {
        if (downloadProgress != null) downloadProgress(count, total);
      });

      if (downloadComplete != null) downloadComplete();
    } catch (exception) {
      String msg = '数据请求错误：' + exception.toString();
      _handError(error, msg);
    }
  }

  // 返回错误信息
  Future _handError(Function errorCallback, String errorMsg) {
    if (errorCallback != null) {
      errorCallback(errorMsg);
    }
  }
}
